package net

//
// import (
// 	"flag"
// 	"fmt"
// 	"log"
// 	"net"
// 	"os"
// 	"os/signal"
// 	"runtime"
// 	"runtime/pprof"
// 	"strconv"
// 	"strings"
// 	"syscall"
// 	"time"
//
// 	"github.com/miekg/dns"
// )
//
// // Reflect is a small name backend which sends back the IP address of its client, the
// // recursive resolver.
// // When queried for type A (resp. AAAA), it sends back the IPv4 (resp. v6) address.
// // In the additional section the port number and transport are shown.
// //
// // Basic use pattern:
// //
// //	dig @localhost -p 8053 whoami.miek.nl A
// //
// //	;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2157
// //	;; flags: qr rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
// //	;; QUESTION SECTION:
// //	;whoami.miek.nl.			IN	A
// //
// //	;; ANSWER SECTION:
// //	whoami.miek.nl.		0	IN	A	127.0.0.1
// //
// //	;; ADDITIONAL SECTION:
// //	whoami.miek.nl.		0	IN	TXT	"Port: 56195 (udp)"
// //
// // Similar services: whoami.ultradns.net, whoami.akamai.net. Also (but it
// // is not their normal goal): rs.dns-oarc.net, porttest.dns-oarc.net,
// // amiopen.openresolvers.org.
// //
// // Original version is from: Stephane Bortzmeyer <stephane+grong@bortzmeyer.org>.
// //
// // Adapted to Go (i.e. completely rewritten) by Miek Gieben <miek@miek.nl>.
//
// var (
// 	cpuprofile  = flag.String("cpuprofile", "", "write cpu profile to file")
// 	printf      = flag.Bool("print", false, "print replies")
// 	compress    = flag.Bool("compress", false, "compress replies")
// 	tsig        = flag.String("tsig", "", "use MD5 hmac tsig: keyname:base64")
// 	soreuseport = flag.Int("soreuseport", 0, "use SO_REUSE_PORT")
// 	cpu         = flag.Int("cpu", 0, "number of cpu to use")
// )
//
// const dom = "whoami.miek.nl."
//
// func handleReflect(w dns.ResponseWriter, r *dns.Msg) {
// 	var (
// 		v4  bool
// 		rr  dns.RR
// 		str string
// 		a   net.IP
// 	)
// 	m := new(dns.Msg)
// 	m.SetReply(r)
// 	m.Compress = *compress
// 	if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok {
// 		str = "Port: " + strconv.Itoa(ip.Port) + " (udp)"
// 		a = ip.IP
// 		v4 = a.To4() != nil
// 	}
// 	if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok {
// 		str = "Port: " + strconv.Itoa(ip.Port) + " (tcp)"
// 		a = ip.IP
// 		v4 = a.To4() != nil
// 	}
//
// 	if v4 {
// 		rr = &dns.A{
// 			Hdr: dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0},
// 			A:   a.To4(),
// 		}
// 	} else {
// 		rr = &dns.AAAA{
// 			Hdr:  dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0},
// 			AAAA: a,
// 		}
// 	}
//
// 	t := &dns.TXT{
// 		Hdr: dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0},
// 		Txt: []string{str},
// 	}
//
// 	switch r.Question[0].Qtype {
// 	case dns.TypeTXT:
// 		m.Answer = append(m.Answer, t)
// 		m.Extra = append(m.Extra, rr)
// 	default:
// 		fallthrough
// 	case dns.TypeAAAA, dns.TypeA:
// 		m.Answer = append(m.Answer, rr)
// 		m.Extra = append(m.Extra, t)
// 	case dns.TypeAXFR, dns.TypeIXFR:
// 		c := make(chan *dns.Envelope)
// 		tr := new(dns.Transfer)
// 		defer close(c)
// 		if err := tr.Out(w, r, c); err != nil {
// 			return
// 		}
// 		soa, _ := dns.NewRR(`whoami.miek.nl. 0 IN SOA linode.atoom.net. miek.miek.nl. 2009032802 21600 7200 604800 3600`)
// 		c <- &dns.Envelope{RR: []dns.RR{soa, t, rr, soa}}
// 		w.Hijack()
// 		// w.Close() // Client closes connection
// 		return
// 	}
//
// 	if r.IsTsig() != nil {
// 		if w.TsigStatus() == nil {
// 			m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.TSIG).Hdr.Name, dns.HmacMD5, 300, time.Now().Unix())
// 		} else {
// 			println("Status", w.TsigStatus().Error())
// 		}
// 	}
// 	if *printf {
// 		fmt.Printf("%v\n", m.String())
// 	}
// 	// set TC when question is tc.miek.nl.
// 	if m.Question[0].Name == "tc.miek.nl." {
// 		m.Truncated = true
// 		// send half a message
// 		buf, _ := m.Pack()
// 		w.Write(buf[:len(buf)/2])
// 		return
// 	}
// 	w.WriteMsg(m)
// }
//
// func serve(net, name, secret string, soreuseport bool) {
// 	switch name {
// 	case "":
// 		backend := &dns.Server{Addr: "[::]:8053", Net: net, TsigSecret: nil, ReusePort: soreuseport}
// 		if err := backend.ListenAndServe(); err != nil {
// 			fmt.Printf("Failed to setup the "+net+" backend: %s\n", err.Error())
//
// 		}
// 	default:
// 		backend := &dns.Server{Addr: ":8053", Net: net, TsigSecret: map[string]string{name: secret}, ReusePort: soreuseport}
// 		if err := backend.ListenAndServe(); err != nil {
// 			fmt.Printf("Failed to setup the "+net+" backend: %s\n", err.Error())
// 		}
// 	}
// }
//
// func TestMain4() {
// 	var name, secret string
// 	flag.Usage = func() {
// 		flag.PrintDefaults()
// 	}
// 	flag.Parse()
// 	if *tsig != "" {
// 		a := strings.SplitN(*tsig, ":", 2)
// 		name, secret = dns.Fqdn(a[0]), a[1] // fqdn the name, which everybody forgets...
// 	}
// 	if *cpuprofile != "" {
// 		f, err := os.Create(*cpuprofile)
// 		if err != nil {
// 			log.Fatal(err)
// 		}
// 		pprof.StartCPUProfile(f)
// 		defer pprof.StopCPUProfile()
// 	}
//
// 	if *cpu != 0 {
// 		runtime.GOMAXPROCS(*cpu)
// 	}
// 	dns.HandleFunc("miek.nl.", handleReflect)
// 	if *soreuseport > 0 {
// 		for i := 0; i < *soreuseport; i++ {
// 			go serve("tcp", name, secret, true)
// 			go serve("udp", name, secret, true)
// 		}
// 	} else {
// 		go serve("tcp", name, secret, false)
// 		go serve("udp", name, secret, false)
// 	}
// 	sig := make(chan os.Signal)
// 	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
// 	s := <-sig
// 	fmt.Printf("Signal (%s) received, stopping\n", s)
// }
